package com.zxl.app.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zxl.common.exception.BusinessException;
import com.zxl.common.model.bo.wx.ActiveAccountBo;
import com.zxl.common.model.pojo.SysMember;
import com.zxl.common.model.vo.WxUserLoginVo;
import com.zxl.common.service.SysMemberService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author zxw
 * @date 2023/3/31
 */
@Service
@Slf4j
public class WxMaUserService {
    @Resource
    private SysMemberService sysMemberService;
    @Resource
    private WxMaService wxMaService;


    /**
     * 第一次登陆
     *
     * @param sessionKey
     * @param token
     * @param member
     */
    public void firstLogin(String sessionKey, String token, SysMember member) {
        member.setSessionKey(sessionKey);
        member.setToken(token);
        if (member.getId() != null) {
            sysMemberService.updateById(member);
        } else {
            sysMemberService.save(member);
        }
    }

    public WxUserLoginVo updateKeyInfo(SysMember record, String token, String sessionKey, SysMember member) {
        WxUserLoginVo wxUserLoginVo = new WxUserLoginVo();
        SysMember entity = new SysMember();
        entity.setId(record.getId());
        entity.setToken(token);
        entity.setUnionId(member.getUnionId());
        entity.setUpdateTime(new Date());
        entity.setSessionKey(sessionKey);
        entity.setOpenId(member.getOpenId());
        sysMemberService.updateById(entity);

        wxUserLoginVo.setToken(token);
        wxUserLoginVo.setPhone(record.getPhone());
        wxUserLoginVo.setOpenId(member.getOpenId());

        return wxUserLoginVo;

    }

    @Transactional(rollbackFor = Exception.class)
    public WxUserLoginVo activeAccount(ActiveAccountBo bo) {
        WxMaJscode2SessionResult sessionInfo;
        try {
            sessionInfo = wxMaService.jsCode2SessionInfo(bo.getJsCode());
        } catch (WxErrorException e) {
            log.error(e.toString());
            throw new BusinessException(e.getError().getErrorMsg());
        }
        WxUserLoginVo res = new WxUserLoginVo();

        //校验是否已注册用户：手机号，token不等于空
        SysMember whenMember = sysMemberService.getBaseMapper().selectOne(new QueryWrapper<SysMember>().eq("open_id", sessionInfo.getOpenid()));
        if (whenMember != null && StrUtil.isNotBlank(whenMember.getPhone()) && StrUtil.isNotBlank(whenMember.getToken())) {
            log.info("获取到历史用户");
            res.setPhone(whenMember.getPhone());
            res.setOpenId(whenMember.getOpenId());
            res.setToken(whenMember.getToken());
        } else {
            SysMember member;
            if (whenMember == null) {
                // 新增用户操作
                member = new SysMember();
                member.setOpenId(sessionInfo.getOpenid());
                member.setUnionId(sessionInfo.getUnionid());
                member.setSessionKey(sessionInfo.getSessionKey());
                sysMemberService.save(member);
            } else {
                member = sysMemberService.getById(whenMember.getId());
            }

            //新用户就注册
            String sessionKey = sessionInfo.getSessionKey();
            String encryptedData = bo.getEncryptedData();
            String iv = bo.getIv();
            log.info("绑定手机号 参数: " + JSONObject.toJSONString(bo));
            if (StrUtil.isBlank(encryptedData) && StrUtil.isBlank(iv)) {
                throw new BusinessException("参数获取失败");
            }
            // 服务端解密用户信息
            // 处理微信号没有绑定手机号问题
            WxMaPhoneNumberInfo userInfo = null;
            try {
                userInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
                if (userInfo == null || userInfo.getPurePhoneNumber() == null) {
                    log.error("用户未绑定手机号, 解析结果 -> " + JSONObject.toJSONString(userInfo) + "\n参数: " + JSONObject.toJSONString(bo));
                    throw new BusinessException("绑定手机号失败, 未获取到微信绑定的手机号");
                }
            } catch (Exception e) {
                throw new BusinessException(e.getMessage());
            }

            String phoneNumber = userInfo.getPurePhoneNumber();
            SysMember record = sysMemberService.getOne(new QueryWrapper<SysMember>().eq("phone", phoneNumber));
            if (record != null) {
                throw new BusinessException("该手机号已被绑定, 请更换手机号");
            }
            SysMember entity = new SysMember();
            String token = UUID.randomUUID().toString();
            entity.setNickName("用户" + phoneNumber);
            entity.setId(member.getId());
            entity.setPhone(phoneNumber);
            entity.setToken(token);
            // sessionKey不同 则更新
            if (!member.getSessionKey().equals(sessionInfo.getSessionKey())) {
                entity.setSessionKey(sessionInfo.getSessionKey());
            }
            sysMemberService.updateById(entity);
            res.setPhone(phoneNumber);
            res.setOpenId(member.getOpenId());
            res.setToken(token);

        }

        return res;
    }
}
